package cn.edu.hust.cm.lib.andro;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore;
import cn.edu.hust.cm.lib.IOUtils;

/**
 * 扩展的可用于Android的IO操作工具集
 * 
 * @author 陈明
 * @since 2012-08-11
 * @version 1.0
 * 
 */
public class IOUtilsExt {
	/**
	 * 缺省的目标文件名
	 */
	public static final String DEFAULT_DEST_NAME = "file";

	/**
	 * 将assets资源中名为assetName的资源文件拷贝到当前程序的file目录, 并以destName命名
	 * 
	 * @param context
	 *            当前程序上下文
	 * @param assetName
	 *            待拷贝的资源文件名
	 * @param destName
	 *            拷贝时的目标文件名
	 * @return 拷贝成功(目标文件长度与待拷贝的文件长度一致)则返回true, 否则返回false
	 * 
	 * @throws IllegalArgumentException
	 *             当 assetName或destName为空
	 */
	public static boolean saveAssetAs(Context context, String assetName,
			String destName) {
		String name = destName;
		if (null == assetName || "".equals(assetName) || null == name
				|| "".equals(name)) {
			throw new IllegalArgumentException("bad filename");
		}

		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		try {
			bis = new BufferedInputStream(context.getAssets().open(assetName));
			// FIXME 这里使用available是否合适
			int expected = bis.available();

			// 如果已经存在, 则先删除
			context.deleteFile(name);

			bos = new BufferedOutputStream(context.openFileOutput(name,
					Context.MODE_APPEND));
			// 由于android asset的限制, Integer.MAX_VALUE是合理的. 可分析AssetInputStream
			int actual = (int) IOUtils.copy(bis, bos, Integer.MAX_VALUE);
			return expected == actual;
		} catch (FileNotFoundException e) {
			System.err.println(e.getMessage());
		} catch (IOException e) {
			System.err.println(e.getMessage());
		} finally {
			if (!IOUtils.close(bis)) {
				System.err.println("inputstream关闭失败");
			}
			if (!IOUtils.close(bos)) {
				System.err.println("outputstream关闭失败");
			}
		}
		return false;
	}

	/**
	 * 获取<strong>表示文件系统中某个文件的uri</strong>对应的绝对文件路径,
	 * 
	 * @param context
	 *            当前程序上下文
	 * @param uri
	 *            目标uri
	 * @return 如果uri的scheme为content, 则返回对应的绝对路径, 否则直接返回uri对应的path
	 * 
	 * @throws IllegalArgumentException
	 *             当uri为null, 或者<strong>这个uri不是表示文件系统中的某个文件</strong>
	 */
	public static String getAbsolutePath(Context context, Uri uri) {
		if (null == uri) {
			throw new IllegalArgumentException();
		}

		String scheme = uri.getScheme();

		if ("content".equals(scheme)) {
			String[] proj = { MediaStore.Images.Media.DATA };
			Cursor cursor = context.getContentResolver().query(uri, proj, null,
					null, null);
			String res = "";
			if (null != cursor && cursor.moveToFirst()) {
				// TODO 需要使用cursor.getColumnIndexOrThrow??
				int index = cursor.getColumnIndexOrThrow(proj[0]);
				res = cursor.getString(index);
				cursor.close();
			} else {
				AndroidLog.w("!!!take care!!! will return empty string as absolute path");
			}

			return res;
		} else {
			// 处理scheme为file等其他情况的uri
			return uri.getPath();
		}
	}
}
